package com.hnjfzn.auth.service;

import com.hnjfzn.auth.form.RegisterBody;
import com.hnjfzn.common.core.constant.CacheConstants;
import com.hnjfzn.common.core.constant.Constants;
import com.hnjfzn.common.core.constant.SecurityConstants;
import com.hnjfzn.common.core.constant.UserConstants;
import com.hnjfzn.common.core.domain.R;
import com.hnjfzn.common.core.exception.ServiceException;
import com.hnjfzn.common.core.utils.SaltUtil;
import com.hnjfzn.common.core.utils.StringUtils;
import com.hnjfzn.common.redis.service.RedisService;
import com.hnjfzn.common.security.utils.SecurityUtils;
import com.hnjfzn.system.api.RemoteUserService;
import com.hnjfzn.system.api.domain.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class SysAuthService {
    @Autowired
    private RemoteUserService remoteUserService;
    @Autowired
    private SysRecordLogService recordLogService;
    @Autowired
    private RedisService redisService;

    public void logout(String loginName)
    {
        recordLogService.recordLogininfor(loginName, Constants.LOGOUT, "退出成功");
    }

    /**
     * 注册
     */
    public void register(RegisterBody registerBody) {
        String username = registerBody.getUsername();
        String password = registerBody.getPassword();
        String realName = registerBody.getRealName();
        String phone = registerBody.getPhoneNumber();
        // 用户名或密码为空 错误
        if (StringUtils.isAnyBlank(username, password)){
            throw new ServiceException("用户/密码必须填写");
        }
        // 验证姓名
        if (StringUtils.isEmpty(realName)){
            throw new ServiceException("姓名必须填写");
        }
        // 验证码用户名
        if (username.length() < UserConstants.USERNAME_MIN_LENGTH
                || username.length() > UserConstants.USERNAME_MAX_LENGTH)
        {
            throw new ServiceException("账户长度必须在2到20个字符之间");
        }
        // 验证码手机号
        if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
                || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
        {
            throw new ServiceException("密码长度必须在5到20个字符之间");
        }
        // 姓名长度验证
        if (realName.length() < UserConstants.NAME_MIN_LENGTH
                || realName.length() > UserConstants.NAME_MAX_LENGTH)
        {
            throw new ServiceException("姓名长度必须在2到50个字符之间");
        }
        // 手机号
        if (!phone.matches("^1[3-9]\\d{9}$")) {
            throw new ServiceException("请输入正确的手机号");
        }
        // 缓存锁
        String lockKey = CacheConstants.REGISTER_LOCK_KEY.concat(username).concat("@").concat(phone);
        // 获取 Redis 中的锁（使用 SETNX）
        boolean isLockAcquired = redisService.setIfAbsent(lockKey, "locked");
        // 如果获取锁失败，说明该用户已经在其他线程/进程注册中
        if (!isLockAcquired) {
            throw new ServiceException("请勿重复注册");
        }
        try {
            // 设置锁的过期时间，防止死锁（假设注册流程在 5 秒内完成）
            redisService.expire(lockKey, 5, TimeUnit.SECONDS);

            // 注册用户信息
            SysUser sysUser = new SysUser();
            sysUser.setUserName(username);
            sysUser.setNickName(realName);
            sysUser.setPhonenumber(phone);
            // 密码
            sysUser.setSalt(SaltUtil.generateSalt());
            sysUser.setPassword(SecurityUtils.encryptPassword(password, sysUser.getSalt()));
            R<?> registerResult = remoteUserService.registerUserInfo(sysUser, SecurityConstants.INNER);
            // 注册失败
            if (R.FAIL == registerResult.getCode())
            {
                throw new ServiceException(registerResult.getMsg());
            }
            recordLogService.recordLogininfor(username, Constants.REGISTER, "注册成功");
        } finally {
            // 操作完成后，删除锁
            redisService.deleteObject(lockKey);
        }
    }
}
